package cn.sdack.go.users.service;

import cn.sdack.go.common.entities.users.*;
import cn.sdack.go.users.dao.*;
import jakarta.transaction.Transactional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationToken;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * @author sdack
 * @date 2024/1/9
 */
@Service
public class UserRoleServiceImpl implements UserRoleService {

    @Autowired
    private UserRoleDao userRoleDao;

    @Autowired
    private RoleDao roleDao;

    @Autowired
    private UserDao userDao;

    @Autowired
    private RoleAuthorityDao roleAuthorityDao;

    @Autowired
    private UserAuthorityDao userAuthorityDao;

    @Autowired
    private AuthorityDao authorityDao;

    /**
     * 用户拥有的权限
     * @param userId
     * @return
     */
    @Override
    public List<AuthorityEntity> userAuthorityList(Long gid,Long userId) throws IllegalAccessException {
        List<RoleEntity> roleList = this.userRoleList(gid,userId);
        List<String> roles = roleList.stream().map(RoleEntity::getCode).collect(Collectors.toList());
        List<RoleAuthorityEntity> list = roleAuthorityDao.findAllByGidAndRoleCodeInAndDelIsNull(gid,roles);
        List<String> authorityKeys = list.stream().map(RoleAuthorityEntity::getAuthorityCode).distinct().collect(Collectors.toList());
        List<UserAuthorityEntity> all = userAuthorityDao.findAllByUserId(userId);
        List<AuthorityEntity> all1 = authorityDao.findAllByGidAndCodeIn(gid, authorityKeys);
        for (UserAuthorityEntity entity : all) {
            AuthorityEntity build = AuthorityEntity.builder().code(entity.getAuthorityCode()).name("").build();
            build.setGid(gid);
            all1.add(build);
        }
        return all1;
    }

    /**
     * 用户拥有的角色
     * @param userId
     * @return
     */
    @Override
    public List<RoleEntity> userRoleList(Long gid,Long userId) throws IllegalAccessException {
        Optional<UserEntity> optional = userDao.findById(userId);
        if (optional.isEmpty()) {
            throw new IllegalAccessException("用户获取失败");
        }
        UserEntity userEntity = optional.get();
        List<UserRoleEntity> userRoleList = userRoleDao.findAllByGidAndUserIdAndDelIsNull(gid,userId);
        List<String> roleKeys = userRoleList.stream().filter(it -> it.getDel() == null).map(UserRoleEntity::getRoleCode).collect(Collectors.toList());
        return roleDao.findAllByGidAndCodeIn(gid,roleKeys);
    }

    /**
     * 拥有此角色的用户
     * @param roleCode
     * @return
     * @throws IllegalAccessException
     */
    @Override
    public List<UserEntity> roleUserList(String roleCode) throws IllegalAccessException {
        JwtAuthenticationToken authentication = (JwtAuthenticationToken) SecurityContextHolder.getContext().getAuthentication();
        Long gid = 0L;
        try {
            gid = Long.parseLong(authentication.getToken().getClaim("gid").toString());
        } catch (Exception e) {
            throw new IllegalAccessException("权限不存在");
        }
        List<UserRoleEntity> all = userRoleDao.findAllByGidAndRoleCodeAndDelIsNull(gid,roleCode);
        List<Long> userIds = all.stream().map(UserRoleEntity::getUserId).collect(Collectors.toList());
        return userDao.findAllById(userIds);
    }

    @Transactional
    @Override
    public void authority(Long gid,Long userId, List<String> list) throws Exception {
        LocalDateTime now = LocalDateTime.now();
        JwtAuthenticationToken authentication = (JwtAuthenticationToken) SecurityContextHolder.getContext().getAuthentication();
        String role = "";
        try {
            role = authentication.getToken().getClaim("role").toString();
        } catch (Exception e) {
            throw new IllegalAccessException("权限检查失败");
        }
        Optional<UserEntity> optional = userDao.findById(userId);
        if (optional.isEmpty()) {
            throw new IllegalAccessException("用户不存在");
        }
        UserEntity userEntity = optional.get();
        if (userEntity.getDel() != null) {
            throw new IllegalAccessException("用户已删除");
        }
        if (UserEntity.Identity.ADMIN.code.equals(role)) {
            if (UserEntity.Identity.SUPER.code.equals(userEntity.getIdentity())) {
                throw new IllegalAccessException("无权授予此用户权限，你的等级不足");
            }
        }
        if (UserEntity.Identity.GROUP_ADMIN.code.equals(role)) {
            if (UserEntity.Identity.SUPER.code.equals(userEntity.getIdentity()) || UserEntity.Identity.ADMIN.code.equals(userEntity.getIdentity())) {
                throw new IllegalAccessException("无权授予此用户权限，你的等级不足");
            }
        }
        if (UserEntity.Identity.GROUP.code.equals(role)) {
            if (UserEntity.Identity.SUPER.code.equals(userEntity.getIdentity()) || UserEntity.Identity.ADMIN.code.equals(userEntity.getIdentity())
                    || UserEntity.Identity.GROUP_ADMIN.code.equals(userEntity.getIdentity())) {
                throw new IllegalAccessException("无权授予此用户权限，你的等级不足");
            }
        }
        if (UserEntity.Identity.SIMPLE.code.equals(role)) {
            if (UserEntity.Identity.SUPER.code.equals(userEntity.getIdentity()) || UserEntity.Identity.ADMIN.code.equals(userEntity.getIdentity())
                    || UserEntity.Identity.GROUP_ADMIN.code.equals(userEntity.getIdentity())) {
                throw new IllegalAccessException("无权授予此用户权限，你的等级不足");
            }
        }
        List<UserRoleEntity> all = userRoleDao.findAllByGidAndUserIdAndDelIsNull(gid,userId);
        all.forEach(it -> it.setDel(now));

        ArrayList<UserRoleEntity> res = new ArrayList<>();
        for (String roleKey : list) {
            RoleEntity roleEntity = roleDao.findByGidAndCodeAndDelIsNull(gid,roleKey);
            if (roleEntity == null) {
                continue;
            }
            Optional<UserRoleEntity> optional1 = all.stream().filter(it -> roleKey.equals(it.getRoleCode())).findAny();
            if (optional1.isPresent()) { // 存在 继续使用
                UserRoleEntity userRoleEntity = optional1.get();
                userRoleEntity.setDel(null);
                userRoleEntity.setGid(gid);
                res.add(userRoleEntity);
            } else { // 新增
                UserRoleEntity build = UserRoleEntity.builder().userId(userId).roleCode(roleKey).build();
                build.setGid(gid);
                build.setAccount(userEntity.getAccount());
                res.add(build);
            }
        }
        userRoleDao.saveAll(res);
        // 把用户已有授权中不存在此次授权的 删除
        userRoleDao.saveAll(all);
    }


    /**
     * 设置当前组织的超级管理员权限
     * @param userId
     * @throws Exception
     */
    @Transactional
    @Override
    public void setAdmin(Long userId) throws Exception {
        JwtAuthenticationToken authentication = (JwtAuthenticationToken) SecurityContextHolder.getContext().getAuthentication();
        String role;
        String newRole = UserEntity.Identity.GROUP.code;
        long pid = 0;
        long uid = 0;
        try {
            pid = Long.parseLong(authentication.getToken().getClaim("pid").toString());
            uid = Long.parseLong(authentication.getToken().getClaim("uid").toString());
            role = authentication.getToken().getClaim("role");
        } catch (Exception e) {
            throw new IllegalAccessException("权限不存在");
        }
        if (!StringUtils.hasLength(role)) {
            throw new IllegalAccessException("权限不存在");
        }
        if (!UserEntity.Identity.SUPER.code.equals(role) && !UserEntity.Identity.ADMIN.code.equals(role)) {
            throw new IllegalAccessException("您没有超级管理权限");
        }
        if (!UserEntity.Identity.GROUP_ADMIN.code.equals(role)  && !UserEntity.Identity.GROUP.code.equals(role)) {
            throw new IllegalAccessException("您没有组织管理权限");
        }
        Optional<UserEntity> optional = userDao.findById(userId);
        if (optional.isEmpty()) {
            throw new IllegalAccessException("用户不存在");
        }
        if (UserEntity.Identity.SUPER.code.equals(role)) {
            pid = uid;
        }
        if (UserEntity.Identity.GROUP_ADMIN.code.equals(role)) {
            pid = uid;
        }
        UserEntity userEntity = optional.get();
        if (UserEntity.Identity.SUPER.code.equals(role) && UserEntity.Identity.ADMIN.code.equals(role)) {
            newRole = UserEntity.Identity.ADMIN.code;
        }
        if (UserEntity.Identity.GROUP_ADMIN.code.equals(role) && UserEntity.Identity.GROUP.code.equals(role)) {
            newRole = UserEntity.Identity.GROUP.code;
        }
        userEntity.setIdentity(newRole);
        // 授权
        // 找到父级的权限
        List<RoleEntity> roleList = this.userRoleList(userEntity.getGid(),pid)
                .stream().filter(it -> it.getGid() == userEntity.getGid().longValue()).collect(Collectors.toList());
        userDao.save(userEntity);
        for (RoleEntity r : roleList) {
            UserRoleEntity.UserRoleEntityBuilder builder = UserRoleEntity.builder();
            builder.userId(userEntity.getId())
                    .account(userEntity.getAccount())
                    .roleCode(r.getCode())
                    .remark(r.getName());
            userRoleDao.save(builder.build());
        }
    }


}
